Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prune unreachable packages from lockfile #6959

Merged
merged 3 commits into from
Sep 4, 2024
Merged

Conversation

konstin
Copy link
Member

@konstin konstin commented Sep 3, 2024

In transformers, we have:

  • tensorflow-text: tensorflow-macos; python_full_version >= '3.13' and platform_machine == 'arm64' and platform_system == 'Darwin'
  • tensorflow-macos: tensorflow-cpu-aws; (python_full_version < '3.10' and platform_machine == 'aarch64' and platform_system == 'Linux') or (python_full_version >= '3.13' and platform_machine == 'aarch64' and platform_system == 'Linux') or (python_full_version >= '3.13' and platform_machine == 'arm64' and platform_system == 'Linux')
  • tensorflow-macos: tensorflow-intel; python_full_version >= '3.13' and platform_system == 'Windows'

This means that tensorflow-cpu-aws and tensorflow-intel can never be installed, and we can drop them from the lockfile.

@konstin konstin added the enhancement New feature or improvement to existing functionality label Sep 3, 2024
konstin added a commit to konstin/packse that referenced this pull request Sep 3, 2024
konstin added a commit to astral-sh/packse that referenced this pull request Sep 3, 2024
Add tests for astral-sh/uv#6959 and
astral-sh/uv#6961.

Tested with:

```toml
[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["unreachable-package", "unreachable-wheels", "requires-python-wheels"]

[tool.uv]
index-url = "http://localhost:3141"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

Lockfile:
```toml
version = 1
requires-python = ">=3.10"

[[package]]
name = "foo"
version = "0.1.0"
source = { editable = "." }
dependencies = [
    { name = "requires-python-wheels" },
    { name = "unreachable-package" },
    { name = "unreachable-wheels" },
]

[package.metadata]
requires-dist = [
    { name = "requires-python-wheels" },
    { name = "unreachable-package" },
    { name = "unreachable-wheels" },
]

[[package]]
name = "requires-python-wheels"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "requires-python-wheels-a" },
]
sdist = { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels-0.0.0.tar.gz", hash = "sha256:79ffa0fd695959b2dbee964c9990516db032ce8983af43c6d9b32ff4a84499a9" }

[[package]]
name = "requires-python-wheels-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0.tar.gz", hash = "sha256:9a11ff73fdc513c4dab0d3e137f4145a00ef0dfc95154360c8f503eed62a03c9" }
wheels = [
    { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0-cp310-cp310-any.whl", hash = "sha256:b979494a0d7dc825b84d6c516ac407143915f6d2840d229ee2a36b3d06deb61d" },
    { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0-cp311-cp311-any.whl", hash = "sha256:b979494a0d7dc825b84d6c516ac407143915f6d2840d229ee2a36b3d06deb61d" },
]

[[package]]
name = "unreachable-package"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "unreachable-package-a", marker = "sys_platform == 'win32'" },
]
sdist = { url = "http://localhost:3141/packages/unreachable-package/unreachable_package-0.0.0.tar.gz", hash = "sha256:f5d940dd2f21645b87d052b22042cca4d10e5af1c456d32946325eb36eea818e" }

[[package]]
name = "unreachable-package-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-package/unreachable_package_a-1.0.0.tar.gz", hash = "sha256:308f0b6772e99dcb33acee38003b176e3acffbe01c3c511585db9a7d7ec008f7" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-package/unreachable_package_a-1.0.0-py3-none-any.whl", hash = "sha256:cc472ded9f3b260e6cda0e633fa407a13607e190422cb455f02beebd32d6751f" },
]

[[package]]
name = "unreachable-wheels"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "unreachable-wheels-a", marker = "sys_platform == 'win32'" },
    { name = "unreachable-wheels-b", marker = "sys_platform == 'linux'" },
    { name = "unreachable-wheels-c", marker = "sys_platform == 'darwin'" },
]
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels-0.0.0.tar.gz", hash = "sha256:6a1da25cbd20e512e219dae85569f20208377d16c004a3e1c5bcbd615c5f5e9e" }

[[package]]
name = "unreachable-wheels-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_a-1.0.0.tar.gz", hash = "sha256:91c6619d1cfa227f3662c0c062b1c0c16efe11e589db2f1836e809e2c6d9961e" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_a-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:e9fb30c5eb114114f9031d0ad2238614c2dcce203c5992848305ccda8f38a53e" },
]

[[package]]
name = "unreachable-wheels-b"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0.tar.gz", hash = "sha256:253ae69b963651cd5ac16601a445e2e179db9eac552e8cfc37aadf73a88931ed" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3de2212ca86f1137324965899ce7f48640ed8db94578f4078d641520b77e13e" },
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:a3de2212ca86f1137324965899ce7f48640ed8db94578f4078d641520b77e13e" },
]

[[package]]
name = "unreachable-wheels-c"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_c-1.0.0.tar.gz", hash = "sha256:5c4783e85f0fa57b720fd02b5c7e0ff8bc98121546fe2cce435710efe4a34b28" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_c-1.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4b846c5b1646b04828a2bef6c9d180ff7cfd725866013dcec8933de7fb5f9e8d" },
]
```
Looks all correct
}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A DFS / BFS wasn't sufficient for creating the marker expressions for pip compile --universal. That's why we have propagate_markers. Is there a reason that it's different here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to guarantee that you've visited every parent before you visit any child.

Copy link
Member Author

@konstin konstin Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

propagate_markers is updating the graph itself and not considering the starting environments, so i found it easier to create a separate method.

The algorithm is a variant of Dijkstra's algorithm for not totally ordered distances: Whenever we find a shorter distance to a node (a marker that is not a subset of the existing marker), we re-queue the node and update all its children: We may not have visited all parents yet, but if a parent propagates an update, we will also propagate it to all children. This implicitly handles cycles, whenever we re-reach a node through a cycle the marker we have is a more specific marker/longer path, so we don't update the node and don't re-queue it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is true, can you update propagate_markers to use the same algorithm? We shouldn’t have two implementations of the same technique.

@charliermarsh
Copy link
Member

How do these even make it into the graph in the first place? 🤔 Is there any way for us to prevent it?

zanieb pushed a commit to konstin/packse that referenced this pull request Sep 3, 2024
Add tests for astral-sh/uv#6959 and
astral-sh/uv#6961.

Tested with:

```toml
[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["unreachable-package", "unreachable-wheels", "requires-python-wheels"]

[tool.uv]
index-url = "http://localhost:3141"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

Lockfile:
```toml
version = 1
requires-python = ">=3.10"

[[package]]
name = "foo"
version = "0.1.0"
source = { editable = "." }
dependencies = [
    { name = "requires-python-wheels" },
    { name = "unreachable-package" },
    { name = "unreachable-wheels" },
]

[package.metadata]
requires-dist = [
    { name = "requires-python-wheels" },
    { name = "unreachable-package" },
    { name = "unreachable-wheels" },
]

[[package]]
name = "requires-python-wheels"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "requires-python-wheels-a" },
]
sdist = { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels-0.0.0.tar.gz", hash = "sha256:79ffa0fd695959b2dbee964c9990516db032ce8983af43c6d9b32ff4a84499a9" }

[[package]]
name = "requires-python-wheels-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0.tar.gz", hash = "sha256:9a11ff73fdc513c4dab0d3e137f4145a00ef0dfc95154360c8f503eed62a03c9" }
wheels = [
    { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0-cp310-cp310-any.whl", hash = "sha256:b979494a0d7dc825b84d6c516ac407143915f6d2840d229ee2a36b3d06deb61d" },
    { url = "http://localhost:3141/packages/requires-python-wheels/requires_python_wheels_a-1.0.0-cp311-cp311-any.whl", hash = "sha256:b979494a0d7dc825b84d6c516ac407143915f6d2840d229ee2a36b3d06deb61d" },
]

[[package]]
name = "unreachable-package"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "unreachable-package-a", marker = "sys_platform == 'win32'" },
]
sdist = { url = "http://localhost:3141/packages/unreachable-package/unreachable_package-0.0.0.tar.gz", hash = "sha256:f5d940dd2f21645b87d052b22042cca4d10e5af1c456d32946325eb36eea818e" }

[[package]]
name = "unreachable-package-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-package/unreachable_package_a-1.0.0.tar.gz", hash = "sha256:308f0b6772e99dcb33acee38003b176e3acffbe01c3c511585db9a7d7ec008f7" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-package/unreachable_package_a-1.0.0-py3-none-any.whl", hash = "sha256:cc472ded9f3b260e6cda0e633fa407a13607e190422cb455f02beebd32d6751f" },
]

[[package]]
name = "unreachable-wheels"
version = "0.0.0"
source = { registry = "http://localhost:3141/" }
dependencies = [
    { name = "unreachable-wheels-a", marker = "sys_platform == 'win32'" },
    { name = "unreachable-wheels-b", marker = "sys_platform == 'linux'" },
    { name = "unreachable-wheels-c", marker = "sys_platform == 'darwin'" },
]
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels-0.0.0.tar.gz", hash = "sha256:6a1da25cbd20e512e219dae85569f20208377d16c004a3e1c5bcbd615c5f5e9e" }

[[package]]
name = "unreachable-wheels-a"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_a-1.0.0.tar.gz", hash = "sha256:91c6619d1cfa227f3662c0c062b1c0c16efe11e589db2f1836e809e2c6d9961e" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_a-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:e9fb30c5eb114114f9031d0ad2238614c2dcce203c5992848305ccda8f38a53e" },
]

[[package]]
name = "unreachable-wheels-b"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0.tar.gz", hash = "sha256:253ae69b963651cd5ac16601a445e2e179db9eac552e8cfc37aadf73a88931ed" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3de2212ca86f1137324965899ce7f48640ed8db94578f4078d641520b77e13e" },
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_b-1.0.0-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:a3de2212ca86f1137324965899ce7f48640ed8db94578f4078d641520b77e13e" },
]

[[package]]
name = "unreachable-wheels-c"
version = "1.0.0"
source = { registry = "http://localhost:3141/" }
sdist = { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_c-1.0.0.tar.gz", hash = "sha256:5c4783e85f0fa57b720fd02b5c7e0ff8bc98121546fe2cce435710efe4a34b28" }
wheels = [
    { url = "http://localhost:3141/packages/unreachable-wheels/unreachable_wheels_c-1.0.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4b846c5b1646b04828a2bef6c9d180ff7cfd725866013dcec8933de7fb5f9e8d" },
]
```
Looks all correct
In transformers, we have:

* `tensorflow-text`: `tensorflow-macos; python_full_version >= '3.13' and platform_machine == 'arm64' and platform_system == 'Darwin'`
* `tensorflow-macos`: `tensorflow-cpu-aws; (python_full_version < '3.10' and platform_machine == 'aarch64' and platform_system == 'Linux') or (python_full_version >= '3.13' and platform_machine == 'aarch64' and platform_system == 'Linux') or (python_full_version >= '3.13' and platform_machine == 'arm64' and platform_system == 'Linux')`
* `tensorflow-macos`: `tensorflow-intel; python_full_version >= '3.13' and platform_system == 'Windows'`

This means that `tensorflow-cpu-aws` and `tensorflow-intel` can never be installed, and we can drop them from the lockfile.
@konstin konstin force-pushed the konsti/remove-dead-packages branch from 572f670 to e918485 Compare September 4, 2024 08:08
@konstin
Copy link
Member Author

konstin commented Sep 4, 2024

tl;dr: Not without an extra layer of virtual packages or forking.

Say we have A -> B on linux and B -> C on windows. We first process A with A -> B, and then B with B -> C. At this point, we know that B is linux only, so we could drop the B -> C edge. Later, we process a package D (universally included), with D -> B. Now we would need to add back C since it is included again, but this doesn't work since pubgrub needs all it's incompatibilities to be immutable.

To mitigate this, we would need a virtual package for each platform, treating platforms like extras, so e.g. splitting the real B into B[not(windows)] and B[windows], with A[universal] -> B[not(windows)], B[windows] -> C[...], B[not(windows)] -> B, B[windows] -> B, and all packages without platforms being dummies that only force the same version of a package. Since we need to propagate this information across intermediary dependencies, we would have to create virtual packages for all intermediary dependencies, creating a massive virtual dependency tree.

We could also fork every time we see a platform marker, for the known trade-offs.

Cargo has this problem too.

@konstin konstin merged commit b9f2bd1 into main Sep 4, 2024
58 checks passed
@konstin konstin deleted the konsti/remove-dead-packages branch September 4, 2024 08:57
konstin added a commit that referenced this pull request Sep 4, 2024
Add additional tests for #6959 and #6961
@konstin konstin mentioned this pull request Sep 4, 2024
konstin added a commit that referenced this pull request Sep 4, 2024
Add additional tests for #6959 and #6961
konstin added a commit that referenced this pull request Sep 5, 2024
Add additional tests for #6959 and
#6961
@konstin konstin mentioned this pull request Sep 5, 2024
konstin added a commit that referenced this pull request Sep 5, 2024
Follow-up to #6959 and #6961: Use the reachability computation instead
of `propagate_markers` everywhere.

With `marker_reachability`, we have a function that computes for each
node the markers under which it is (`requirements.txt`, no markers
provided on installation) or can be (`uv.lock`, depending on the markers
provided on installation) included in the installation. Put differently:
If the marker computed by `marker_reachability` is not fulfilled for the
current platform, the package is never required on the current platform.

We compute the markers for each package in the graph, this includes the
virtual extra packages and the base packages. Since we know that each
virtual extra package depends on its base package (`foo[bar]` implied
`foo`), we only retain the base package marker in the `requirements.txt`
graph.

In #6959/#6961 we were only using it for pruning packages in `uv.lock`,
now we're also using it for the markers in `requirements.txt`.

I think this closes #4645, CC @bluss.
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Sep 11, 2024
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.4.4` -> `0.4.9` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.4.9`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#049)

[Compare Source](astral-sh/uv@0.4.8...0.4.9)

##### Enhancements

-   Add support for managed Python 3.13 ([#&#8203;7263](astral-sh/uv#7263))
-   Upgrade managed CPython versions to latest patch releases ([#&#8203;7263](astral-sh/uv#7263))
-   Allow setting a target version for `uv self update` ([#&#8203;7252](astral-sh/uv#7252))
-   Create `py.typed` files during `uv init --lib` ([#&#8203;7232](astral-sh/uv#7232))
-   Add a dedicated error for packages that fail due to `distutils` deprecation ([#&#8203;7239](astral-sh/uv#7239))
-   Improve error message when requested Python version is unsupported ([#&#8203;7269](astral-sh/uv#7269))
-   Add `uv run --no-sync` ([#&#8203;7192](\(https://github.com/astral-sh/uv/pull/7192\))

##### Bug fixes

-   Avoid updating `pyproject.toml` offsets on non-add edits ([#&#8203;7262](astral-sh/uv#7262))
-   Invalidate cache when `--config-settings` change ([#&#8203;7139](astral-sh/uv#7139))
-   Remove workspace root for single-member workspace with `uv export` ([#&#8203;7254](astral-sh/uv#7254))

### [`v0.4.8`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#048)

[Compare Source](astral-sh/uv@0.4.7...0.4.8)

##### Enhancements

-   Add support for dynamic cache keys ([#&#8203;7136](astral-sh/uv#7136))
-   Allow `.dist-info` names with dashes for post releases ([#&#8203;7208](astral-sh/uv#7208))
-   Use type hints in code from `uv init` ([#&#8203;7225](astral-sh/uv#7225))
-   Treat `.tgz` the same as `.tar.gz` ([#&#8203;7201](astral-sh/uv#7201))
-   Direct users towards `uv venv` to create a virtual environment ([#&#8203;7188](astral-sh/uv#7188))
-   Improve error message for uv init already init-ed ([#&#8203;7198](astral-sh/uv#7198))

##### Performance

-   Avoid batch prefetching for un-optimized registries ([#&#8203;7226](astral-sh/uv#7226))
-   Avoid iteration for singleton selections ([#&#8203;7195](astral-sh/uv#7195))

##### Bug fixes

-   Avoid extra newlines in debug logging for source builds ([#&#8203;7174](astral-sh/uv#7174))
-   Prune unreachable packages from `--universal` output ([#&#8203;7209](astral-sh/uv#7209))
-   Respect exclusion when collecting workspace members ([#&#8203;7175](astral-sh/uv#7175))
-   Use path file instead of `sitecustomize.py` ([#&#8203;7161](astral-sh/uv#7161))
-   Replace incorrect `--source` and `--binary` flags with correct `--sdist` and `--wheel` flags in `uv build` ([#&#8203;7156](astral-sh/uv#7156))

##### Documentation

-   Document support for `UV_INSTALL_DIR` ([#&#8203;7107](astral-sh/uv#7107))
-   List all supported sdist formats ([#&#8203;7168](astral-sh/uv#7168))

### [`v0.4.7`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#047)

[Compare Source](astral-sh/uv@0.4.6...0.4.7)

##### Enhancements

-   Add `--no-emit-project` and friends to `uv export` ([#&#8203;7110](astral-sh/uv#7110))
-   Add `--output-file` to `uv export` ([#&#8203;7109](astral-sh/uv#7109))
-   Prune unused source distributions from the cache in `uv cache prune` ([#&#8203;7112](astral-sh/uv#7112))
-   Take intersection of constraint and requirements hashes ([#&#8203;7108](astral-sh/uv#7108))

##### Performance

-   Skip metadata fetch for `--no-deps` and `pip sync` ([#&#8203;7127](astral-sh/uv#7127))

##### Bug fixes

-   Avoid panicking when encountering an invalid Python version during `uv python list` ([#&#8203;7131](astral-sh/uv#7131))
-   Write trailing newline to `.python-version` files ([#&#8203;7140](astral-sh/uv#7140))

### [`v0.4.6`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#046)

[Compare Source](astral-sh/uv@0.4.5...0.4.6)

##### Enhancements

-   Accept `--build-constraints` in `uv build` ([#&#8203;7085](astral-sh/uv#7085))
-   Add `--require-hashes` and `--verify-hashes` to `uv build` ([#&#8203;7094](astral-sh/uv#7094))
-   Add `--show-version-specifiers` to `uv tool list` ([#&#8203;7050](astral-sh/uv#7050))
-   Respect hashes in constraints files ([#&#8203;7093](astral-sh/uv#7093))
-   Upgrade installer scripts ([#&#8203;7092](astral-sh/uv#7092))
-   Allow specifying multiple packages in `uv tool upgrade` and `uninstall` ([#&#8203;7037](astral-sh/uv#7037))
-   Sort by implementation in `uv python list` ([#&#8203;6918](astral-sh/uv#6918))

##### Bug fixes

-   Invalidate lockfile when member versions change ([#&#8203;7102](astral-sh/uv#7102))
-   Strip fragments from direct source URLs in lockfile ([#&#8203;7061](astral-sh/uv#7061))
-   Support `--no-build` and `--no-binary` in `uv sync` et al ([#&#8203;7100](astral-sh/uv#7100))
-   Use distribution hash over registry hash ([#&#8203;7060](astral-sh/uv#7060))
-   Fix inverted log message ([#&#8203;7063](astral-sh/uv#7063))
-   Adjust Docker `ENTRYPOINT` and `CMD` for inherited images ([#&#8203;7054](astral-sh/uv#7054))

##### Documentation

-   Add winget to installers ([#&#8203;7088](astral-sh/uv#7088))
-   Document how to disable path modifications during install ([#&#8203;7090](astral-sh/uv#7090))
-   Document how to manually update locked package version ([#&#8203;7083](astral-sh/uv#7083))
-   Document official `setup-uv` action ([#&#8203;7056](astral-sh/uv#7056))
-   Update docs on `.python-version` file ([#&#8203;7051](astral-sh/uv#7051))

### [`v0.4.5`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#045)

[Compare Source](astral-sh/uv@0.4.4...0.4.5)

##### Enhancements

-   Implement `uv build` ([#&#8203;6895](astral-sh/uv#6895))
-   Add `--package` support to `uv build` ([#&#8203;6990](astral-sh/uv#6990))
-   Prune unreachable packages from lockfile ([#&#8203;6959](astral-sh/uv#6959))
-   Prune unreachable wheels from lockfile ([#&#8203;6961](astral-sh/uv#6961))
-   Show build output by default in `uv build` ([#&#8203;6912](astral-sh/uv#6912))
-   Support `uv build --wheel` from source distributions ([#&#8203;6898](astral-sh/uv#6898))
-   Use the root project name for the project virtual environment prompt ([#&#8203;7021](astral-sh/uv#7021))

##### Bug fixes

-   Fix handling of inline optional dependencies in `uv add` ([#&#8203;7023](astral-sh/uv#7023))
-   Reflect exit code in `uv tool run` and `uv run` ([#&#8203;6994](astral-sh/uv#6994))
-   Revert `pyproject.toml` modifications on Ctrl-C ([#&#8203;7024](astral-sh/uv#7024))
-   Rollback `pyproject.toml` changes on all errors ([#&#8203;7022](astral-sh/uv#7022))
-   Use correct ordering semantics for narrowing upper-bounded Python requirements ([#&#8203;7031](astral-sh/uv#7031))
-   Fix segfault in Windows trampolines ([#&#8203;6955](astral-sh/uv#6955))
-   Remove unused `__future__.annotations` import in `_virtualenv.py` ([#&#8203;6996](astral-sh/uv#6996))

##### Documentation

-   Add documentation for `uv build` ([#&#8203;6991](astral-sh/uv#6991))
-   Add note to `extra` and `all-extras` in `uv sync` help ([#&#8203;7013](astral-sh/uv#7013))
-   Add project docs for `project.scripts` ([#&#8203;7010](astral-sh/uv#7010))
-   Fix available Docker image tag rendering and shorten list ([#&#8203;7017](astral-sh/uv#7017))
-   Touchup to the project environment config section ([#&#8203;7038](astral-sh/uv#7038))
-   Clarify precedence of `uv.toml` ([#&#8203;6986](astral-sh/uv#6986))
-   Fix available Docker tags for `-slim` variants ([#&#8203;7041](astral-sh/uv#7041))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement to existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants